﻿using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Collections.Generic;
using System.Threading.Tasks;
using WorkFlow.Data;
using WorkFlow.Data.Model;

namespace WorkFlow.Pages
{
    public partial class RuleDetail
    {
        private IJSObjectReference myJSModule;
        private IJSObjectReference module;
        [Parameter]
        public string RuleID
        {
            get; set;
        }
        private RuleEntity _RuleEntity;
        private List<RuleDetailEntity> _AllRuleDetailEntities;

        private List<RuleDetailEntity> Items { get; set; }
        private RuleDetailEntity _EditRuleDetailEntity = new RuleDetailEntity();
        private string _OprationType;
        protected override void OnParametersSet()
        {
            commentTool.ShowNav = false;
            base.OnParametersSet();
        }
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                myJSModule = await JSRunTime.InvokeAsync<IJSObjectReference>("import", "/vendor/MyJS.js");
                module = await JSRunTime.InvokeAsync<IJSObjectReference>("import", "./bootstrap/js/bootstrap-treeview.min.js");
                //组件实例封装：
                DotNetObjectReference.Create(this);
                //类实例封装：
                var classInstance = new RuleDetail();
                DotNetObjectReference.Create(classInstance);
                // 注入当前实例
                await myJSModule.InvokeVoidAsync("BindDetailInstance", DotNetObjectReference.Create(this));

                BindData(true);
            }
        }

        private void InitItems(int id)
        {
            RuleDetailEntity parentNode = _AllRuleDetailEntities.Find(a => a.ID == id);
            List<RuleDetailEntity> ruleDetailEntities = _AllRuleDetailEntities.FindAll(a => a.ParentID == id);
            parentNode.Nodes = ruleDetailEntities;
            foreach (RuleDetailEntity item in ruleDetailEntities)
            {
                //item.state["selected"] = false;
                InitItems(item.ID);
            }
        }
        private List<RuleDetailEntity> GetTreeItems()
        {
            List<RuleDetailEntity> result = new List<RuleDetailEntity>();
            result.Add(new RuleDetailEntity(0, 0, "a", "1"));
            result.Add(new RuleDetailEntity(0, 1, "b", "2"));
            result.Add(new RuleDetailEntity(0, 2, "c", "3"));
            result.Add(new RuleDetailEntity(0, 3, "d", "4"));
            result.Add(new RuleDetailEntity(0, 4, "e", "5"));
            result.Add(new RuleDetailEntity(0, 5, "f", "6"));
            return result;
        }
        private async void AddOpration(string opration)
        {
            _OprationType = opration;
            if (_OprationType == "|")
            {
                //object obj = await myJSModule.InvokeAsync<object>("GetCheckList");
            }
            List<RuleDetailEntity> ruleDetailEntitys = await myJSModule.InvokeAsync<List<RuleDetailEntity>>("GetCheckList");
            RuleDetailEntity parentNode = ruleDetailEntitys.Count > 0 ? ruleDetailEntitys[0] : null;
            if (parentNode == null && Items.Count > 0)
            {
                await myJSModule.InvokeVoidAsync("alertMsg", "Need Choose ParentNode!");
                await myJSModule.InvokeVoidAsync("CloseDialog", "close");
                return;
            }
            _EditRuleDetailEntity = new RuleDetailEntity();
            _EditRuleDetailEntity.IsNew = true;
            _EditRuleDetailEntity.Type = CommentTool.GetOprationIntType(opration);
            if (parentNode != null)
            {
                _EditRuleDetailEntity.ParentID = parentNode.ID;
            }
            if (parentNode != null && parentNode.Type > 3)
            {
                await myJSModule.InvokeVoidAsync("alertMsg", $"this '{CommentTool.GetOprationStrType(parentNode.Type)}' can't add '{opration}'");
                return;
            }
            switch (opration)
            {
                case "&":
                case "|":
                case "!":

                    Save();
                    break;
                case "=":
                case "!=":
                case ">":
                case ">=":
                case "<":
                case "<=":
                    _EditRuleDetailEntity.ValueType = 1;
                    await myJSModule.InvokeVoidAsync("ShowModal", "EditRuleDetail");
                    break;
                default:
                    break;
            }
            BindData();
        }

        private async void Edit()
        {
            RuleDetailEntity currentNode = await GetCurrentNode();
            if (currentNode == null)
            {
                await myJSModule.InvokeVoidAsync("alertMsg", "Need Choose RuleNode!");
                return;
            }
            _EditRuleDetailEntity = currentNode;
            await myJSModule.InvokeVoidAsync("ShowModal", "EditRuleDetail");
            UpdateUI();
        }
        private async Task<RuleDetailEntity> GetCurrentNode()
        {
            List<RuleDetailEntity> ruleDetailEntitys = await myJSModule.InvokeAsync<List<RuleDetailEntity>>("GetCheckList");
            RuleDetailEntity currentNode = ruleDetailEntitys.Count > 0 ? ruleDetailEntitys[0] : null;
            // Update selected states
            if (currentNode != null)
            {
                currentNode = _AllRuleDetailEntities.Find(a => a.ID == currentNode.ID);
            }
            return currentNode;
        }
        private async void Delete()
        {
            RuleDetailEntity currentNode = await GetCurrentNode();
            if (currentNode == null)
            {
                await myJSModule.InvokeVoidAsync("alertMsg", "Need Choose RuleNode!");
                return;
            }
            if (currentNode.Nodes.Count > 0)
            {
                await myJSModule.InvokeVoidAsync("alertMsg", "Please delete children nodes first!");
                return;
            }
            dataManager.DeleteRuleDetailEntity(currentNode);
            _AllRuleDetailEntities.Remove(currentNode);
            BindData();
        }
        private void ClearSelected()
        {
            foreach (RuleDetailEntity item in _AllRuleDetailEntities)
            {
                item.state["selected"] = false;
            }
        }
        [JSInvokable]
        public Task<bool> ItemOnClick(RuleDetailEntity ruleDetailEntity)
        {
            if (ruleDetailEntity != null)
            {
                ClearSelected();
                _AllRuleDetailEntities.Find(a => a.ID == ruleDetailEntity.ID).state["selected"] = true;
            }
            return Task.FromResult(true);
        }
        private async void Save()
        {
            if (_EditRuleDetailEntity.IsNew)
            {
                int detailID = dataManager.InsertRuleDetailEntity(_EditRuleDetailEntity);

                if (Items.Count == 0)
                {
                    dataManager.UpdateRule_DetailID(_RuleEntity.ID, detailID);
                }

                ClearSelected();
                RuleDetailEntity ruleDetailEntity = dataManager.GetRuleDetails(detailID);
                ruleDetailEntity.state["selected"] = true;
                _AllRuleDetailEntities.Add(ruleDetailEntity);
            }
            else
            {
                dataManager.UpdateRuleDetailEntity(_EditRuleDetailEntity);
            }
            await myJSModule.InvokeVoidAsync("CloseDialog", "close");
            BindData();
        }

        private async void BindData(bool isFirst = false)
        {
            Items = new List<RuleDetailEntity>();
            _RuleEntity = dataManager.GetRule(int.Parse(RuleID))[0];
            if (isFirst)
            {
                _AllRuleDetailEntities = dataManager.GetRuleDetails();
            }
            RuleDetailEntity rootNode = _AllRuleDetailEntities.Find(a => a.ID == _RuleEntity.RuleDetailID);
            if (rootNode != null)
            {
                if (isFirst)
                {
                    rootNode.state["selected"] = true;
                }
                Items.Add(rootNode);
                InitItems(rootNode.ID);
            }
            await myJSModule.InvokeVoidAsync("BindTreeView", Items);
            UpdateUI();
        }
        private async void UpdateUI()
        {
            await InvokeAsync(() => StateHasChanged());
        }

    }
}
